<!--
 * @Description: 电话号码组件
 * @Author: luozhong
 * @Date: 2020-09-05 21:59:07
-->
<template>
  <div class="phone-number-content">
    <div v-if="onlyView" class="view">
      <div class="label">Phone number</div>
      <div class="value">{{ `${countryCode}${phoneNumber}` }}</div>
    </div>
    <div v-else class="phone-form">
      <phone-code v-model="countryCode" only-icon :style="{ height: height + 'px' }" />
      <gg-input
        v-if="hasOtherCode"
        :style="{ height: height + 'px', width: codeWidth, position: 'relative', left: '0' }"
        :value="countryCode"
        inline
        class="phone-form-input code"
        :class="[{ 'md-focused': isFocus }, { 'md-invalid': isError.show }]"
      />
      <gg-input
        :style="{ height: height + 'px' }"
        v-model="phoneNumber"
        inline
        placeholder="Phone *"
        class="phone-form-input"
        :class="{ 'has-area-code': hasOtherCode }"
        :error="isError"
        @focus="isFocus = true"
        @blur="isFocus = false"
        ref="contactNumber"
      />
    </div>
  </div>
</template>

<script>
import { debounce } from 'lodash';

export default {
  name: 'phoneNumber',
  props: {
    value: {
      type: Object,
      default: () => ({
        countryCode: '+65',
        phoneNumber: ''
      })
    },
    height: {
      type: Number,
      default: 30
    },
    title: {
      type: String,
      default: 'Phone number *'
    },
    titleStyle: {
      type: Object,
      default: () => {}
    },
    editing: {
      type: Boolean,
      default: true
    },
    onlyView: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      phoneChange: false,
      countryCode: this.value.countryCode,
      phoneNumber: this.value.phoneNumber,
      isFocus: false
    };
  },
  computed: {
    tipColor() {
      if (this.isError.show) {
        return '#ea4335';
      }
      return this.isFocus && this.editing ? '#1a73e8' : '';
    },
    hasOtherCode() {
      return this.countryCode !== '+65' && this.countryCode !== '';
    },
    isError() {
      if (this.phoneChange && this.phoneNumber === '') {
        return {
          message: 'Phone number required',
          show: true,
          val: this.phoneNumber
        };
      }
      if (!/^[0-9]*$/.test(this.phoneNumber)) {
        return {
          message: 'Invalid phone number',
          show: true,
          val: this.phoneNumber
        };
      }
      // 不可超过11个字符
      let isPass = /^\d{0,11}$/.test(this.phoneNumber);
      return {
        message: 'Character limit of 11',
        show: !isPass,
        val: this.phoneNumber
      };
    },
    codeWidth() {
      if (this.countryCode === '+65') {
        return 0;
      }
      return `${this.countryCode.length * 10 + 3}px`;
    }
  },
  mounted() {
    this.phoneChange = false;
  },
  watch: {
    // 去除空格和.
    phoneNumber: debounce(function (res) {
      this.phoneChange = true;
      this.phoneNumber = res.replace(/\s+|\./g, '');
      this.$emit('input', {
        countryCode: this.countryCode,
        phoneNumber: this.phoneNumber
      });
    }, 300),
    countryCode() {
      this.$emit('input', {
        countryCode: this.countryCode,
        phoneNumber: this.phoneNumber
      });
    },
    value(res) {
      this.countryCode = res.countryCode;
      this.phoneNumber = res.phoneNumber;
    },
    isError: {
      deep: true,
      immediate: true,
      handler(res) {
        this.initErrorStyle();
        this.$emit('isError', res.show);
      }
    },
    codeWidth() {
      this.initErrorStyle();
    }
  },
  methods: {
    initErrorStyle() {
      this.$nextTick(() => {
        if (this.isError.show) {
          const errorDom = document.querySelector('.phone-form-input .md-error');
          if (errorDom) {
            errorDom.style.marginLeft = `-${this.codeWidth}`;
          }
        }
      });
    }
  }
};
</script>

<style lang="less" scoped>
.phone-number-content {
  padding-bottom: 20px;
  position: relative;
  margin-bottom: 19px;
}
.view {
  display: flex;
  color: #202124;
  font-size: 16px;
  font-family: Roboto;
  .label {
    margin-right: 100px;
  }
}
.phone-form {
  display: flex;
  align-items: flex-start;
  position: relative;
  font-family: Roboto;
  color: #202124;
  .area-code {
    width: 33px;
    position: absolute;
    left: 88px;
    font-size: 16px;
  }
  > p {
    font-size: 12px;
  }
  > div {
    height: 30px;
    min-height: 30px;
  }
  .phone-form-input {
    /deep/ .md-error {
      opacity: 1;
      bottom: -21px;
    }
    /deep/ .md-input {
      height: 100%;
      box-sizing: border-box;
      &::-webkit-outer-spin-button,
      &::-webkit-inner-spin-button {
        -webkit-appearance: none;
      }
      &[type='number'] {
        -moz-appearance: textfield;
      }
    }
    &.code.focus::after {
      opacity: 0;
    }
    // &.has-area-code {
    //   /deep/ .md-input {
    //     text-indent: 35px;
    //   }
    // }
  }
  /deep/ .md-field {
    margin: 0;
    padding: 0;
  }
  /deep/ .el-select {
    height: 100% !important;
  }
  /deep/ .el-input {
    height: 100% !important;
  }
  /deep/ .phone {
    width: 64px;
    margin-right: 28px;
    .el-select .el-input {
      border-bottom: none;
      input {
        width: 35px;
      }
    }
    .iconfont.flag {
      width: 2em;
      height: 2em;
      top: 50%;
      transform: translateY(-50%);
    }
    .el-input__suffix {
      height: 20px;
      position: static;
    }
    .el-input--suffix {
      display: flex;
      align-items: center;
      cursor: pointer;
    }
    .el-select__caret {
      transform-origin: center;
      width: 20px;
      height: 20px;
      text-align: center;
      line-height: 20px;
    }
  }
  /deep/ .md-input::-webkit-input-placeholder {
    color: #b4b4b4 !important;
  }

  /deep/ .md-input::-moz-placeholder {
    color: #b4b4b4 !important;
  }

  /deep/ .md-input:-ms-input-placeholder {
    color: #b4b4b4 !important;
  }
}
</style>
